package com.ruoyi.qd.task;

import cn.hutool.core.date.DateUtil;
import com.mybatisflex.core.query.QueryMethods;
import com.ruoyi.qd.domain.Order;
import com.ruoyi.qd.domain.Robot;
import com.ruoyi.qd.domain.RobotQueue;
import com.ruoyi.qd.enums.OrderStatusEnum;
import com.ruoyi.qd.enums.RobotEnableStatusEnum;
import com.ruoyi.qd.enums.RobotOnlineStatusEnum;
import com.ruoyi.qd.enums.RobotQueueStatusEnum;
import com.ruoyi.qd.enums.TradeWaterTypeEnum;
import com.ruoyi.qd.service.ITradeWaterService;
import com.ruoyi.qd.vo.TradeWaterAddReq;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import java.util.Date;
import java.util.List;
import java.util.Objects;

import static com.ruoyi.qd.domain.table.RobotQueueTableDef.ROBOT_QUEUE;

@Component("robotQueueTask")
public class RobotQueueTask {
    @Autowired
    private ITradeWaterService tradeWaterService;
    @Autowired
    private RobotQueueTask robotQueueTask;

    public void statusChange() {
        List<Long> robotIds = Robot.create()
                .select(Robot::getId)
                .where(Robot::getOnlineStatus).eq(RobotOnlineStatusEnum.YES.getCode())
                .and(Robot::getEnableStatus).eq(RobotEnableStatusEnum.YES.getCode())
                .listAs(Long.class);
        for (Long robotId : robotIds) {
            robotQueueTask.changeStatusReal(robotId);
        }
    }

    @Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRES_NEW)
    public void changeStatusReal(Long robotId) {
        // 呼叫中等待了30s还没到签到的号设置状态为已过期
        RobotQueue robotQueue = RobotQueue.create()
                .where(RobotQueue::getRobotId).eq(robotId)
                .and(RobotQueue::getStatus).eq(RobotQueueStatusEnum.CALL.getCode())
                .and(QueryMethods.unixTimestamp(ROBOT_QUEUE.CALL_TIME).add(30)
                        .lt(DateUtil.currentSeconds()))
                .one();
        if (Objects.nonNull(robotQueue)) {
            // 设置队列状态为已过期
            RobotQueue.create()
                    .setStatus(RobotQueueStatusEnum.EXPIRED.getCode())
                    .where(RobotQueue::getId).eq(robotQueue.getId())
                    .update();

            // 过号退款
            Order order = Order.create().where(Order::getId).eq(robotQueue.getOrderId()).one();
            TradeWaterAddReq tradeWaterAddReq = new TradeWaterAddReq();
            tradeWaterAddReq.setAmount(order.getMoney());
            tradeWaterAddReq.setType(TradeWaterTypeEnum.PASS_NUMBER_REFUND.getCode());
            tradeWaterAddReq.setUserId(order.getUserId());
            tradeWaterService.add(tradeWaterAddReq);

            // 修改订单状态为过号
            Order.create()
                    .setStatus(OrderStatusEnum.PASS_NUMBER.getCode())
                    .where(Order::getId).eq(order.getId())
                    .update();
        }

        long count = RobotQueue.create()
                .where(RobotQueue::getRobotId).eq(robotId)
                .and(RobotQueue::getStatus).in(RobotQueueStatusEnum.CALL.getCode(),
                        RobotQueueStatusEnum.PROCESS.getCode())
                .count();
        // 有呼叫中的不做处理
        if (count == 1) {
            return;
        }

        // 将排队中按预约时间顺序由小到大排序并且是当天时间的取第一条，设置状态为呼叫中
        RobotQueue.create()
                .setStatus(RobotQueueStatusEnum.CALL.getCode())
                .setCallTime(new Date())
                .where(RobotQueue::getRobotId).eq(robotId)
                .and(RobotQueue::getStatus).eq(RobotQueueStatusEnum.LINE.getCode())
                .and(QueryMethods.dateFormat(RobotQueue::getAppointmentTime, "%Y-%m-%d")
                        .eq(DateUtil.today()))
                .orderBy(RobotQueue::getAppointmentTime).asc()
                .limit(1)
                .update();
    }

}
